/**
 * 
 */
package com.zufangbao.earth.web.controller.finance;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.demo2do.core.entity.Result;
import com.demo2do.core.persistence.support.Filter;
import com.demo2do.core.utils.DateUtils;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.utils.StringUtils;
import com.demo2do.core.web.interceptor.InfoMessage;
import com.demo2do.core.web.interceptor.MenuSetting;
import com.demo2do.core.web.resolver.Page;
import com.demo2do.core.web.resolver.Secure;
import com.zufangbao.earth.entity.security.Principal;
import com.zufangbao.sun.entity.company.corp.App;
import com.zufangbao.sun.entity.order.TransactionRecord;
import com.zufangbao.sun.entity.order.TransactionRecordStatus;
import com.zufangbao.sun.service.AppService;
import com.zufangbao.sun.service.OrderService;
import com.zufangbao.sun.service.TransactionRecordService;

/**
 * @author mohanlan
 *
 */

@Controller
@RequestMapping("/receipt")
@MenuSetting("menu-finance")
public class ReceiptController {
	
	private static final Log logger = LogFactory.getLog(ReceiptController.class);
	
	@Autowired
	private OrderService orderService;
	@Autowired
	private TransactionRecordService transactionRecordService;
	@Autowired
	private AppService appService;
	/**
	 * return unpaid checking list
	 * 
	 * @return
	 */
	@RequestMapping("/checking/unpaid")
	@MenuSetting("submenu-receipt-checking")
	public ModelAndView checkingUnpaid(Page page){
		
		ModelAndView modelAndView = new ModelAndView("finance/checking-unpaid");
		
	    com.demo2do.core.persistence.support.Order orderByDate = new com.demo2do.core.persistence.support.Order().add("lastModifiedTime", "DESC");

		List<TransactionRecord> transactionRecordList = transactionRecordService.list(TransactionRecord.class, new Filter().addEquals("transactionRecordStatus", TransactionRecordStatus.CREATED), orderByDate, page);

		modelAndView.addObject("transactionRecordList", transactionRecordList);
		modelAndView.addObject("page", page);
		
		return modelAndView;
		
	}
	
	/**
	 * return paid checking list
	 * 
	 * @return
	 */
	@RequestMapping(value = {"/checking", "/checking/paid"} )
	@MenuSetting("submenu-receipt-checking")
	public ModelAndView checkingPaid(Page page){
		
		ModelAndView modelAndView = new ModelAndView("finance/checking-paid");
		
	    com.demo2do.core.persistence.support.Order orderByDate = new com.demo2do.core.persistence.support.Order().add("lastModifiedTime", "DESC");

		List<TransactionRecord> transactionRecordList = transactionRecordService.list(TransactionRecord.class, new Filter().addEquals("transactionRecordStatus", TransactionRecordStatus.PAID), orderByDate, page);
		
		modelAndView.addObject("transactionRecordList", transactionRecordList);
		modelAndView.addObject("page", page);
		
		return modelAndView;
		
	}
	
	/**
	 * 
	 * @return
	 */
	@RequestMapping(value = {"/checking/search", "/checking/unpaid/search"})
	public ModelAndView search() {

		ModelAndView modelAndView = new ModelAndView("finance/receipt-unpaid-search");

		return modelAndView;
	}

	/**
	 * 
	 * @return
	 */
	@RequestMapping(value = {"/checking/search", "/checking/unpaid/search"}, method = RequestMethod.GET, params = "filter")
	@MenuSetting("submenu-receipt-checking")
	public ModelAndView onSearch(HttpServletRequest request,
							     @RequestParam(value = "tradeNo", required = false) String tradeNo,
							     Page page) {

		ModelAndView modelAndView = new ModelAndView("finance/checking-unpaid");
	
		// create Filter first
		Filter filter = new Filter();
		if(!tradeNo.isEmpty()){
			filter.addEquals("tradeNo", tradeNo);
		}

		List<TransactionRecord> transactionRecordList = transactionRecordService.list(TransactionRecord.class, filter.addEquals("transactionRecordStatus", TransactionRecordStatus.CREATED), page);

		// handle query string
		String queryString = request.getQueryString();
		Map<String, String> queries = StringUtils.parseQueryString(queryString);
		if(queries.containsKey("page")) {
			queries.remove("page");
		}
		
		modelAndView.addObject("transactionRecordList", transactionRecordList);
		modelAndView.addObject("queryString", StringUtils.toQueryString(queries));
		
		return modelAndView;
	}
	
	/**
	 * 
	 * @return
	 */
	@RequestMapping("/checking/paid/search")
	public ModelAndView paidSearch() {

		ModelAndView modelAndView = new ModelAndView("finance/receipt-paid-search");

		return modelAndView;
	}

	/**
	 * 
	 * @return
	 */
	@RequestMapping(value ="/checking/paid/search", method = RequestMethod.GET, params = "filter")
	@MenuSetting("submenu-receipt-checking")
	public ModelAndView paidOnSearch(HttpServletRequest request,
							     @RequestParam(value = "tradeNo", required = false) String tradeNo,
							     Page page) {

		ModelAndView modelAndView = new ModelAndView("finance/checking-paid");
	
		// create Filter first
		Filter filter = new Filter();
		if(!tradeNo.isEmpty()){
			filter.addEquals("tradeNo", tradeNo);
		}

		List<TransactionRecord> transactionRecordList = transactionRecordService.list(TransactionRecord.class, filter.addEquals("transactionRecordStatus", TransactionRecordStatus.PAID), page);

		// handle query string
		String queryString = request.getQueryString();
		Map<String, String> queries = StringUtils.parseQueryString(queryString);
		if(queries.containsKey("page")) {
			queries.remove("page");
		}
		
		modelAndView.addObject("transactionRecordList", transactionRecordList);
		modelAndView.addObject("queryString", StringUtils.toQueryString(queries));
		
		return modelAndView;
	}
	
	/**
	 * support transaction record 
	 * @return
	 */
	@RequestMapping("/{transactionRecordID}/support")
	public ModelAndView support(@PathVariable("transactionRecordID")Long transactionRecordID) {
		
		TransactionRecord transactionRecord = transactionRecordService.load(TransactionRecord.class, transactionRecordID);
		
		ModelAndView modelAndView = new ModelAndView("finance/transaction-record-support");
		modelAndView.addObject("transactionRecord", transactionRecord);

		return modelAndView;
	}
	
	/**
	 * support transaction record 
	 * @return
	 */
	@RequestMapping(value="/{transactionRecordID}/support", method = RequestMethod.POST)
	@InfoMessage("info.transaction-record.support.success")
	public String onSupport(Page page, @PathVariable("transactionRecordID")Long transactionRecordID,
			@RequestParam(value = "tradeNo", required = false)String tradeNo,
			@Secure Principal principal) {

		TransactionRecord transactionRecord = transactionRecordService.load(TransactionRecord.class, transactionRecordID);
		if(!orderService.supportTransactionRecord(transactionRecord, tradeNo, principal.getId())){
			logger.error("ReceiptController#onSupport - onSupport transactionRecord failed at " + DateUtils.getCurrentTimeMillis()+"transactionId ="+transactionRecordID);
		}
		
		return "redirect:/receipt/checking/paid";
	}
	
	/**
	 * support transaction record 
	 * @return
	 */
	@RequestMapping("/{transactionRecordID}/confirm")
	public ModelAndView confirm(@PathVariable("transactionRecordID")Long transactionRecordID) {
		
		TransactionRecord transactionRecord = transactionRecordService.load(TransactionRecord.class, transactionRecordID);
		
		ModelAndView modelAndView = new ModelAndView("finance/transaction-record-confirm");
		modelAndView.addObject("transactionRecord", transactionRecord);

		return modelAndView;
	}
	
	/**
	 * support transaction record 
	 * @return
	 */
	@RequestMapping(value="/{transactionRecordID}/confirm", method = RequestMethod.POST)
	@InfoMessage("info.transaction-record.confirm.success")
	public String onConfirm(Page page, @PathVariable("transactionRecordID")Long transactionRecordID, @Secure Principal principal) {

		TransactionRecord transactionRecord = transactionRecordService.load(TransactionRecord.class, transactionRecordID);
		if(!orderService.confirmTransactionRecord(transactionRecord, principal.getId())){
			logger.error("ReceiptController#onSupport - onConfirm transactionRecord failed at " + DateUtils.getCurrentTimeMillis()+"transactionId ="+transactionRecordID);
		}
		
		return "redirect:/receipt/checking/paid";

	}
	
	@RequestMapping("/sync-nativeorder")
	public @ResponseBody String syncOrder(@RequestParam("appId") String appId,
			@RequestParam("orderNo") String orderNo,
			@RequestParam("tradeNo") String tradeNo,
			@RequestParam("paidRent") String  paidRent,
			@RequestParam("payDate") String payDate) {
		
		logger.info("sync-nativeorder:appId"+appId+"orderNo="+orderNo+"tradeNo="+tradeNo+"paidRent="+paidRent);
		Result result = new Result();
					
		// parse paidRent to BigDeicimal
		BigDecimal paidMoney = new BigDecimal(paidRent);
		
		App app = appService.getApp(appId);
		Date payTime = DateUtils.parseDate(payDate, "yyyy-MM-dd HH:mm:SS");
		orderService.syncNativeOrder(orderNo, tradeNo, app, payTime, paidMoney, result);
				
		return JsonUtils.toJsonString(result);
	}

}
